package org.jeecg.modules.demo.douyin;


import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.demo.api.UpmsHelloApi;
import org.jeecg.modules.demo.entity.Dept;
import org.jeecg.modules.demo.mall.api.MallHelloApi;
import org.jeecg.modules.demo.weixin.douyin.config.DYConfig;
import org.jeecg.modules.demo.weixin.douyin.dto.DyCheckDto;
import org.jeecg.modules.demo.weixin.douyin.dto.DyQueryOrderDto;
import org.jeecg.modules.demo.weixin.douyin.dto.DyQueryShopDto;
import org.jeecg.modules.demo.weixin.douyin.dto.DyVerificationDto;
import org.jeecg.modules.demo.weixin.douyin.entity.YxDouyinOrder;
import org.jeecg.modules.demo.weixin.douyin.utils.DouYinUtil;
import org.jeecg.modules.demo.weixin.douyin.vo.CheckTicketVo;
import org.jeecg.modules.demo.weixin.douyin.vo.OrderStatusVo;
import org.jeecg.modules.demo.weixin.douyin.vo.PoiVo;
import org.jeecg.modules.demo.weixin.douyin.vo.VerifyResultsVo;
import org.jeecg.modules.demo.weixin.dto.PayDto;
import org.jeecg.modules.demo.weixin.entity.PayOrder;
import org.jeecg.modules.demo.weixin.entity.SmtDouyinTuangou;
import org.jeecg.modules.demo.weixin.entity.SmtYuyueList;
import org.jeecg.modules.demo.weixin.payorder.service.IPayOrderService;
import org.jeecg.modules.demo.weixin.smtdouyintuangou.service.ISmtDouyinTuangouService;
import org.jeecg.modules.demo.weixin.smtyuyuelist.service.ISmtYuyueListService;
import org.jeecg.modules.demo.weixin.smtyuyueuser.mapper.SmtYuyueUserMapper;
import org.jeecg.modules.demo.weixin.smtyuyueuser.service.ISmtYuyueUserService;
import org.jeecg.modules.demo.weixin.util.MD5Util;
import org.jeecg.modules.demo.weixin.yxdouyinorder.service.IYxDouyinOrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/weixin/douyin")/*,method = RequestMethod.POST*/
@Slf4j
public class DouYinController {

    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private IYxDouyinOrderService yxDouyinOrderService;
    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private UpmsHelloApi upmsHelloApi;
    @Autowired
    private MallHelloApi mallHelloApi;
    @Autowired
    private ISmtYuyueListService smtYuyueListService;
    @Autowired
    private ISmtDouyinTuangouService smtDouyinTuangouService;
    @Autowired
    private ISmtYuyueUserService yuyueUserService;
    @Autowired
    private SmtYuyueUserMapper yuyueUserMapper;
    private final BigDecimal TEN_BIG = new BigDecimal(100);

    /**
     * 检验券
     *
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @PostMapping(value = "/examine")
    public Result<?> examine(@Validated @RequestBody DyCheckDto req) throws Exception {
        log.info("请求参数：" + req);
        //获取临时token
        String token = DouYinUtil.auth();
        if (!StringUtils.hasText(token)) {
            return Result.error(606, "token不存在");
        }
        //调用验券准备接口
        CheckTicketVo checkTicket = DouYinUtil.examine(token, req.getCode(), req.getEncrypteData());
        if (checkTicket == null) {
            return Result.error(606, "核销验证准备不正确");
        }
        //查询抖音商品
        SmtDouyinTuangou smtDouyinTuangou = smtDouyinTuangouService.queryDyTuangou(checkTicket.getSkuId());
        if (smtDouyinTuangou == null) {
            Result.error(606, "抖音商品不匹配");
        }
        //查询抖音表是否有数据
        LambdaQueryWrapper<YxDouyinOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YxDouyinOrder::getCertificateId, checkTicket.getCertificateId());
        queryWrapper.eq(YxDouyinOrder::getOrderId,checkTicket.getOrderId());

        YxDouyinOrder yxDouyinOrderOne = yxDouyinOrderService.getOne(queryWrapper);

        //判断是都是抖音此卡  因为此卡在平台发放  抖音支支持 团购  无语此卡次数
//        if (yxDouyinOrderOne != null && checkTicket.getGrouponType() == 3) {
//            if (checkTicket.getTimesUsed() == checkTicket.getTimesCount()) {
//                return Result.error(606, "次卡已使用完");
//            }
//            yxDouyinOrderOne.setTimesUsed(checkTicket.getTimesUsed());
//            yxDouyinOrderOne.setVerifyToken(checkTicket.getVerifyToken());
//            yxDouyinOrderOne.setEncryptedCode(checkTicket.getEncryptedCode());
//            yxDouyinOrderService.updateById(yxDouyinOrderOne);
//        } else
        if (ObjectUtils.isEmpty(yxDouyinOrderOne)) {
            //如果不存在需要进行添加
//            log.info("没有数据走增加接口");
            YxDouyinOrder yxDouyinOrder = new YxDouyinOrder();
            BeanUtils.copyProperties(checkTicket, yxDouyinOrder);
            //查询状态添加
            List<OrderStatusVo> orderStatusVoList = DouYinUtil.queryOrder(token, checkTicket.getOrderId(), checkTicket.getAccountId(), 1, 100);
            if (CollectionUtils.isEmpty(orderStatusVoList)) {
                return Result.error(606, "订单信息没有");
            }
            //状态填写
            orderStatusVoList.forEach(orderStatusVo -> {
                if (orderStatusVo.getCertificateId().equals(checkTicket.getCertificateId())) {
                    BeanUtils.copyProperties(orderStatusVo, yxDouyinOrder);
                }
            });
            YxDouyinOrder one = yxDouyinOrderService.getOne(queryWrapper);
            if (one==null){
                yxDouyinOrderService.save(yxDouyinOrder);
            }
            yxDouyinOrder.setStock(smtDouyinTuangou.getCount());
            return Result.ok(yxDouyinOrder);
        }
        if (yxDouyinOrderOne != null && checkTicket.getGrouponType() != 3) {
            yxDouyinOrderOne.setVerifyToken(checkTicket.getVerifyToken());
            yxDouyinOrderOne.setEncryptedCode(checkTicket.getEncryptedCode());
            yxDouyinOrderService.updateById(yxDouyinOrderOne);
        }

        yxDouyinOrderOne.setStock(smtDouyinTuangou.getCount());
        return Result.ok(yxDouyinOrderOne);
    }

    /**
     * 核销
     *
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @PostMapping(value = "/verification")
    public Result<?> verification(@Validated @RequestBody DyVerificationDto req) throws Exception {
        log.info("请求参数：" + req);
        //获取临时token
        String token = DouYinUtil.auth();
        if (!StringUtils.hasText(token)) {
            return Result.error(606, "token不存在");
        }
        //调用门店接口  查询门店的poiId
        Dept dept = upmsHelloApi.queryByDept(Long.valueOf(Long.valueOf(req.getMerId())));
        if (dept == null) {
            return Result.error(606, "门店不存在");
        }
        SmtYuyueList yuyueList = smtYuyueListService.getById(req.getYuyueId());
        if (yuyueList == null) {
            return Result.error(606, "预约不存在");
        }
        //核销结束查询预约场次  看是都有冲突
        if ((yuyueList.getCount() - yuyueList.getNum()) < req.getNum()) {
            return Result.error(606, "当前排期人数已满，请选择其他排期！");
        }
        yuyueList.setNum(yuyueList.getNum() + req.getNum());

        //核销
        VerifyResultsVo verifyResultsVo = DouYinUtil.verification(token, req.getEncryptedCode(), req.getVerifyToken(), dept.getPoiId());
        if (verifyResultsVo == null) {
            return Result.error(606, "核销不正确");
        }
        //查询订单修改状态
        LambdaQueryWrapper<YxDouyinOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YxDouyinOrder::getCertificateId, verifyResultsVo.getCertificateId());
//        queryWrapper.eq(YxDouyinOrder::getOrderId, verifyResultsVo.getOrderId());
        YxDouyinOrder yxDouyinOrderOne = yxDouyinOrderService.getOne(queryWrapper);
        if (yxDouyinOrderOne == null) {
            return Result.error(606, "订单不存在");
        }
        BeanUtils.copyProperties(verifyResultsVo, yxDouyinOrderOne);
        //查询    状态添加
        List<OrderStatusVo> orderStatusVoList = DouYinUtil.queryOrder(token, yxDouyinOrderOne.getOrderId(), yxDouyinOrderOne.getAccountId(), 1, 100);
        if (CollectionUtils.isEmpty(orderStatusVoList)) {
            return Result.error(606, "订单信息没有");
        }
        //状态填写
        orderStatusVoList.forEach(orderStatusVo -> {
            if (orderStatusVo.getCertificateId().equals(verifyResultsVo.getCertificateId())) {
                BeanUtils.copyProperties(orderStatusVo, yxDouyinOrderOne);
            }
        });
        yxDouyinOrderService.updateById(yxDouyinOrderOne);

        PayOrder payOrder = new PayOrder();
        BeanUtils.copyProperties(req, payOrder);
        //抖音订单本来金额 分  需要转换
        payOrder.setMerchantId(req.getMerId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String orderNo = MD5Util.encryptMd5(simpleDateFormat.format(new Date()) + RandomUtil.randomNumbers(10));
        payOrder.setOrderNo(orderNo);
        payOrder.setTrkName(yxDouyinOrderOne.getTitle());
        payOrder.setCount(req.getNum());
        payOrder.setPayPrice(new BigDecimal(yxDouyinOrderOne.getPayAmount()).divide(TEN_BIG));
        payOrder.setActualPrice(payOrder.getPayPrice());
        payOrder.setTotalPrice(new BigDecimal(yxDouyinOrderOne.getOriginalAmount()).divide(TEN_BIG));
        payOrder.setPayStatus("2");
        payOrder.setCertificateId(yxDouyinOrderOne.getCertificateId());
        payOrder.setPayMode("4");
        payOrder.setOrderType(4);
        payOrder.setPayTime(new Date());
        payOrder.setCount(req.getNum());
        payOrder.setMerchantName(dept.getName());
        payOrder.setPayType("Tiktok");
        payOrder.setSourceType(1);
        payOrderService.save(payOrder);
        PayDto payDto = new PayDto();
        payDto.setOrderCouponNo(payOrder.getOrderNo());
        payDto.setYuYueId(req.getYuyueId());
        payDto.setOrd(yuyueList.getOrd());
        payDto.setQrCode(yuyueList.getQrCode());
        payDto.setCount(req.getNum());
        //修改预约场次已有人数
        smtYuyueListService.updateById(yuyueList);
        yuyueUserService.saveUser(payDto);

        return Result.ok("核销成功");
    }

    /**
     * 查询店铺
     *
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @PostMapping(value = "/queryShop")
    public Result<?> queryShop(@Validated @RequestBody DyQueryShopDto req) throws Exception {
        log.info("请求参数：" + req);
        //获取临时token
        String token = DouYinUtil.auth();
        if (!StringUtils.hasText(token)) {
            return Result.error(606, "token不存在");
        }
        //查询订单接口
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("account_id", req.getAccountId());
        jsonObject.put("page", req.getPage());
        jsonObject.put("size", req.getSize());
        String result = HttpRequest.get(DYConfig.dyQuery).contentType("application/json").header("access-token", token).form(jsonObject).execute().body();
        JSONObject resultBody = JSONObject.parseObject(result);
        //判断返回是否是0--success
        if (!resultBody.getJSONObject("data").get("error_code").equals(0)) {
            return Result.error(606, "查询失败");
        }
        //获取门店集合   其中没有账号id因为订单查询会用到    不过都是总帐号ID（抖音来客） 验券准备已经返回信息订单查询无需
//        List<JSONObject> poiList = resultBody.getJSONObject("data").getJSONArray("pois").stream().map(item -> ((JSONObject) item)).collect(Collectors.toList());
        List<PoiVo> poiVoList = resultBody.getJSONObject("data").getJSONArray("pois").stream().map(item -> JSON.parseObject(((JSONObject) item).getJSONObject("poi").toString(), PoiVo.class)).collect(Collectors.toList());
        return Result.ok(poiVoList);
    }

    /**
     * 主动查询接口
     *
     * @param req
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @PostMapping(value = "/queryOrder")
    public Result<?> queryOrder(@Validated @RequestBody DyQueryOrderDto req) throws Exception {
        log.info("请求参数：" + req);
        //获取临时token
        String token = DouYinUtil.auth();
        if (!StringUtils.hasText(token)) {
            return Result.error(606, "token不存在");
        }
        //查询状态添加
        List<OrderStatusVo> orderStatusVoList = DouYinUtil.queryOrder(token, req.getOrderId(), req.getAccountId(), 1, 100);
        if (CollectionUtils.isEmpty(orderStatusVoList)) {
            return Result.error(606, "订单信息没有");
        }
        //获取券码id
        Map<String, OrderStatusVo> statusVoMap = orderStatusVoList.stream().collect(Collectors.toMap(OrderStatusVo::getCertificateId, Function.identity()));
        //查询订单
        LambdaQueryWrapper<YxDouyinOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(YxDouyinOrder::getCertificateId, statusVoMap.keySet());
        List<YxDouyinOrder> yxDouyinOrders = yxDouyinOrderService.list(queryWrapper);
        yxDouyinOrders.forEach(yxDouyinOrder -> {
            OrderStatusVo orderStatusVo = statusVoMap.get(yxDouyinOrder.getCertificateId());
            if (null != orderStatusVo) {
                //如果状态是退款中和已经退款
                if (orderStatusVo.getItemStatus() == 301) {
                    yxDouyinOrder.setRefundAmount(orderStatusVo.getRefundAmount());
                    yxDouyinOrder.setRefundtime(orderStatusVo.getRefundTime());
                    LambdaQueryWrapper<PayOrder> orderQueryWrapper = new LambdaQueryWrapper<>();
                    orderQueryWrapper.eq(PayOrder::getCertificateId, orderStatusVo.getCertificateId());
                    PayOrder payone = payOrderService.getOne(orderQueryWrapper);
                    payone.setPayStatus("3");
                    payone.setRefundFee(new BigDecimal(orderStatusVo.getRefundAmount()).divide(TEN_BIG));
                    payone.setRefundTime(new Date(orderStatusVo.getRefundTime() * 1000));
                }
                //更新状态
                yxDouyinOrder.setItemStatus(orderStatusVo.getItemStatus());
            }
        });
        yxDouyinOrderService.updateBatchById(yxDouyinOrders);
        return Result.ok(orderStatusVoList);
    }

    /**
     * 撤销
     *
     * @param req
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @PostMapping(value = "/chexiao")
    public Result<?> chexiao(@Validated @RequestBody DyVerificationDto req) throws Exception{
        log.info("请求参数：" + req);
        //获取临时token
        String token = DouYinUtil.auth();
        if (!StringUtils.hasText(token)) {
            return Result.error(606, "token不存在");
        }
        //获取订单编号
        LambdaQueryWrapper<PayOrder> payOrderLambdaQueryWrapper = new LambdaQueryWrapper<PayOrder>();
        payOrderLambdaQueryWrapper.eq(PayOrder::getOrderNo, req.getOrderNo());
        payOrderLambdaQueryWrapper.eq(PayOrder::getPayStatus, "2");
        PayOrder payOrder = payOrderService.getOne(payOrderLambdaQueryWrapper);
        if (payOrder == null) {
            Result.error("没有抖音团购核销订单信息");
        }
        LambdaQueryWrapper<YxDouyinOrder> douyinWrapper = new LambdaQueryWrapper<YxDouyinOrder>();
        douyinWrapper.eq(YxDouyinOrder::getCertificateId, payOrder.getCertificateId());
        YxDouyinOrder yxDouyinOrder = yxDouyinOrderService.getOne(douyinWrapper);
        if (yxDouyinOrder == null) {
            Result.error("没有核销记录信息");
        }
        //撤销
        Boolean chexiao = DouYinUtil.chexiao(token, yxDouyinOrder.getVerifyId(), yxDouyinOrder.getCertificateId());
        if (chexiao.equals(Boolean.FALSE)){
            return Result.error("撤销失败");
        }
        payOrder.setPayStatus("3");
        if (payOrder.getOrderType() == 3) {
            //根据订单选择的排期id查询排期
            SmtYuyueList yuyueList = smtYuyueListService.getById(payOrder.getYuyueId());
            //减掉占位
            Integer num = yuyueList.getNum() - payOrder.getCount();
            yuyueList.setNum(num);
            smtYuyueListService.updateById(yuyueList);
            //根据预约id查询对应的玩家并修改状态
            yuyueUserMapper.updateStatus(payOrder.getYuyueId(), payOrder.getCount(),null, payOrder.getOrderNo());
        }
        return Result.ok("撤销成功");
    }



}
